;**********************************************
;*@File: ScanKey.asm
;*@Author: Scriptfan <scriptfan@hotmail.com>
;*@Date: 2017-1-14
;*@Description: 扫描（线反转法）检测矩阵键盘按键
;**********************************************
	;定时时长存放地址
	LTIME EQU 030H
	ROW EQU 031H
	COL EQU 032H
	KEY EQU 033H
	ORG 0000H
	LJMP MAIN
	ORG 0100H
MAIN:
	;初始化寄存器
	MOV SP, 04FH
	CLR RS0
	CLR RS1
SCAN:
	;行检测，是否有键按下
	MOV P1, #0FH
	MOV A, P1
	ANL A, #0FH
	CJNE A, #0FH, COMF_ROW
	SJMP SCAN
COMF_ROW:
	;延时12ms
	MOV LTIME, #18H
	LCALL DELAY
	;再次检查是否有键按下
	MOV A, P1
	ANL A, #0FH
	CJNE A, #0FH, OK_ROW
	SJMP SCAN
OK_ROW:
	;确实有键按下
	MOV ROW, A

	;列检测
	MOV P1, #0F0H
	MOV A, P1
	ANL A, #0F0H
	CJNE A, #0F0H, COMF_COL
	SJMP SCAN
COMF_COL:
	;延时12ms
	MOV LTIME, #18H
	LCALL DELAY
	;再次检查是否有键按下
	MOV A, P1
	ANL A, #0F0H
	CJNE A, #0F0H, OK_COL
	SJMP SCAN
OK_COL:
	;确实有键按下
	MOV COL, A
	ORL A, ROW
	MOV KEY, A
	;获得按键值
	LCALL KEYSCAN
	MOV A, KEY
	CPL A
	MOV P3, A

NEXT:
	SJMP SCAN

	LJMP EXIT

;按键编码子程序
KEYSCAN:
	PUSH PSW
	PUSH ACC
	CLR RS0
	SETB RS1
	;循环查找按键值
	MOV R4, #1FH
	MOV R3, #0H
NEXT_KEY:	
	MOV A, R3
	MOV DPTR, #KEYCODE
	MOVC A, @A+DPTR
	MOV R2, A
	INC R3
	DEC R4
	MOV A, R4
	JZ NO_FOUND
	MOV A, R2
	CJNE A, KEY, NEXT_KEY
	;INC R3
	MOV KEY, R3
	SJMP KEY_EXIT
NO_FOUND:
	MOV KEY, #0H
KEY_EXIT:
	POP ACC
	POP PSW
	RET

;延时子程序(最小延时0.5ms)
DELAY:
	PUSH PSW
	PUSH ACC
	CLR RS0
	SETB RS1
	MOV R2, LTIME
LOOP1:
	MOV R3, #0FAH
LOOP2:
	DJNZ R3, LOOP2
	DJNZ R2, LOOP1
	POP ACC
	POP PSW
	RET

;键盘按键码表
KEYCODE:
	DB 0EEH, 0DEH, 0BEH, 7EH
	DB 0EDH, 0DDH, 0BDH, 7DH
	DB 0EBH, 0DBH, 0BBH, 7BH
	DB 0E7H, 0D7H, 0B7H, 77H
;退出程序
EXIT:
	END
